package com.fp.m7.client;

import net.customware.gwt.presenter.client.place.PlaceRequest;
import net.customware.gwt.presenter.client.place.PlaceRequestEvent;

import com.allen_sauer.gwt.log.client.Log;
import com.fp.m7.client.inject.AppGinjector;
import com.fp.m7.client.place.HomePlace;
import com.fp.m7.client.place.TimelinePlace;
import com.fp.m7.client.presenter.AppPresenter;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * A helper class for initializing the whole application using GIN injector. The crucial thing here is to set
 * isForAuthenticatedUser value - this decides which presenter to run (public or secured).
 * 
 * @author 7
 */
public class AppController {

    private static AppController instance;

    private AppGinjector ginjector;

    private MyMessages messages;

    private boolean isForAuthenticatedUser = false;

    private AppController() {
    }

    public static AppController getInstance() {
        if (instance == null) {
            instance = new AppController();
        }
        return instance;
    }

    public boolean isForAuthenticatedUser() {
        return isForAuthenticatedUser;
    }

    public void setForAuthenticatedUser(boolean isForAuthenticatedUser) {
        this.isForAuthenticatedUser = isForAuthenticatedUser;
    }

    public void go(RootPanel rootPanel) {
        AppPresenter<?> appPresenter = getAppPresenter();
        appPresenter.bind();
        appPresenter.revealDisplay();

        rootPanel.add(appPresenter.getDisplay().asWidget());

        Log.setUncaughtExceptionHandler();

        handleHistoryTokens();
    }

    private void handleHistoryTokens() {
        // If there are no tokens on history stack, launch initial state token provided as parameter
        if (History.getToken().length() == 0) {
            if (isForAuthenticatedUser) {
                ginjector.getEventBus().fireEvent(new PlaceRequestEvent(new PlaceRequest(TimelinePlace.NAME)));
            } else {
                ginjector.getEventBus().fireEvent(new PlaceRequestEvent(new PlaceRequest(HomePlace.NAME)));
            }
        } else {
            // We have a token, so let's fire off an event and handle it
            ginjector.getPlaceManager().fireCurrentPlace();
        }
    }

    public AppGinjector getGinjector() {
        if (ginjector == null) {
            ginjector = GWT.create(AppGinjector.class);
        }
        return ginjector;
    }

    public MyMessages getMessages() {
        if (messages == null) {
            messages = GWT.create(MyMessages.class);
        }
        return messages;
    }

    public AppPresenter<?> getAppPresenter() {
        if (isForAuthenticatedUser) {
            return getGinjector().getAppSecuredPresenter();
        } else {
            return getGinjector().getAppPublicPresenter();
        }
    }

}
